﻿using System;
using System.Threading.Tasks;
using HK.Core.Common.Protocol.Control;
using HK.Core.Utils;
using HLogger = HK.Core.Logs.Logger;

namespace HK.Core.Common.Control
{
    /// <summary>
    /// 单例模版类基类.
    /// </summary>
    public abstract class Singleton<T> : ClassExtension, ISingleton
        where T : class, ISingleton, new()
    {
        private static T _instance;
        public static T Instance
        {
            get
            {
                if (default(T) == _instance)
                {
                    _instance = new T();
                }
                if (null != _instance) return _instance;
                
                HLogger.Error($"SingletonBase:Instance new failed!!(Type:{typeof(T).Name})");
                return null;
            }
        }

        /// <summary>
        /// 构造函数.
        /// </summary>
        protected Singleton()
        {
            _instance = this as T;
            SingletonInit();
        }

#region Virtual

        /// <summary>
        /// 初始化标志位
        /// </summary>
        public bool Initialized { get; protected set; } = false;

        /// <summary>
        /// 单例类Init()
        /// </summary>
        public async Task SingletonInit()
        {
#if UNITY_EDITOR
            try
            {
#endif
            
            // 已初始化完成
            if (Initialized) return;
            
            // // 初始化数据
            // await InitData(null);
                
            // 初始化
            Init();
            Initialized = true;
#if UNITY_EDITOR
            }
            catch (Exception exp)
            {
                Fatal("SingletonInit():Exception Caught!" + 
                      $"\n  Exp:{exp.GetType().Name}" +
                      $"\n  Message:{exp.Message}" +
                      $"\n  Source:{exp.Source}" +
                      $"\n  StackTrace:{exp.StackTrace}");
            }
#endif
        }

        /// <summary>   
        /// 初始化
        /// </summary>
        protected virtual void Init()
        {
            // 注册事件
            if (!EventRegistered)
            {
                RegisterEvents();
                EventRegistered = true;
            }
        }
        
        /// <summary>
        /// Dispose
        /// </summary>
        public virtual void Dispose()
        {
            // 尚未初始化
            if(!Initialized) return;
            
            // 释放
            Info("Dispose()");
            Release();
            
            // 重置初始化标志位
            Initialized = false;
        }
        
        /// <summary>
        /// 释放<BR/>
        /// * 真正释放统一调用方法:Dispose()
        /// </summary>
        protected virtual void Release()
        {
            // 移除事件
            if (EventRegistered)
            {
                RemoveEvents();
                EventRegistered = false;
            }
        }

#endregion

#region Data

        // /// <summary>
        // /// 初始化数据
        // /// <para>* 允许异步操作</para>
        // /// </summary>
        // /// <param name="iOnCompleted">完成回调</param>
        // protected virtual async Task InitData(UtilsTask.TaskCompleted iOnCompleted = null)
        // {
        //     await UtilsTask.RunTaskAsync(() => true, iOnCompleted, "InitData");
        // }

#endregion

#region Events

        /// <summary>
        /// 事件已注册标志位
        /// </summary>
        protected bool EventRegistered { get; private set; } = false;
                
        /// <summary>
        /// 注册事件
        /// </summary>
        protected virtual void RegisterEvents() { }

        /// <summary>
        /// 移除事件
        /// </summary>
        protected virtual void RemoveEvents() { }

#endregion

    }
}
